package com.learner.common.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 
 * @author admin
 *
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {

	private static ApplicationContext applicationContext;

	/**
	 * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		SpringContextUtils.applicationContext = applicationContext;
	}

	/**
	 * 取得存储在静态变量中的ApplicationContext.
	 */
	public static ApplicationContext getContext() {
		return applicationContext;
	}

	/**
	 * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name) {
		return (T) applicationContext.getBean(name);
	}

	/**
	 * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(Class<T> clazz) {
		return (T) applicationContext.getBean(clazz);
	}

    /**
     * 获取指定名称和类型的Bean
     * 如果bean不能被类型转换，相应的异常将会被抛出（BeanNotOfRequiredTypeException）
     *
     * @param name         bean注册名
     * @param clazz 返回对象类型
     * @return Object 返回requiredType类型对象
     * @throws BeansException
     */
    public static <T> T getBean(String name, Class<T> clazz) throws BeansException {
        return applicationContext.getBean(name, clazz);
    }

	public static <T> T getBeans(Class<T> clazz) {
		return (T) applicationContext.getBeansOfType(clazz);
	}


	/**
	 * 获取指定名称和类型的Bean
	 * 如果bean不能被类型转换，相应的异常将会被抛出（BeanNotOfRequiredTypeException）
	 *
	 * @param name         bean注册名
	 * @param clazz 返回对象类型
	 * @return Object 返回requiredType类型对象
	 * @throws BeansException
	 */
	public static <T> T getValue(String name, Class<T> clazz) throws BeansException {
		return applicationContext.getEnvironment().getProperty(name,clazz);
	}

	/**
	 * 获取容器启动时的ActiveProfiles，只返回第一个activeProfiles
	 * 注意如果这里配置了多个ActiveProfiles，不要用此方法获取
	 * @return
	 * @throws BeansException
	 */
	public static String getOneActiveProfile() throws BeansException {
		String[] activeProfiles = applicationContext.getEnvironment().getActiveProfiles();
		if(activeProfiles.length == 0){
			return null;
		}
		return activeProfiles[0];
	}
}